#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>

#include "my_assert.h"
#include "mmap.h"
#include "../logger/logger.h"

MMap::MMap(const std::string& file_name, uint64_t default_alloc):
	mapped_addr_(nullptr),
	mapped_size_(0),
	fd_(-1) {
	LOG_FUNCTION("");	

	LOGGER_WRITE(Logger::Priority::INFO, "creating swap file: " + file_name);	
	fd_ = open(file_name.c_str(), O_CREAT | O_RDWR, 0644);
	my_assert(fd_ != -1);
	if (default_alloc) {
//		int ret = fallocate(fd_, 0, 0, default_alloc);
//		my_assert(ret != -1);
	}
}

MMap::~MMap() {
	LOG_FUNCTION("");	
	my_assert(fd_ != -1);
	int ret = close(fd_);
	my_assert(ret == 0);
}

void *MMap::MapRW(uint64_t offset, size_t size) {
	LOG_FUNCTION("");	
	my_assert(!mapped_addr_ && !mapped_size_);
	my_assert(fd_ != -1);
	my_assert(offset % sysconf(_SC_PAGE_SIZE) == 0);
	mapped_addr_ = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
	    fd_, offset);
	my_assert(mapped_addr_);
	my_assert(mapped_addr_ != MAP_FAILED);
	mapped_size_ = size;
	
	return mapped_addr_;
}

void *MMap::GetCurrentMap() {
	LOG_FUNCTION("");	
	my_assert(mapped_addr_ && mapped_size_);
	return mapped_addr_;
}


void MMap::Unmap() {
	LOG_FUNCTION("");	
	my_assert(!mapped_addr_ && !mapped_size_);
	my_assert(fd_ != -1);
	int ret = munmap(mapped_addr_, mapped_size_);
	my_assert(ret != -1);
	mapped_addr_ = nullptr;
	mapped_size_ = 0;
}

bool MMap::IsMapped() {
	LOG_FUNCTION("");	
	return mapped_addr_;
}

